

'''
    takes a csv file
    with id,id,similarity
    write the network file 
    using the backbone with 
    a certain p-value
    and the label file. 
'''

import sys

def update_network(node_i, node_j, sim, node_node_similarity):
    
    '''
        node_i and node_j are ids
        sim is their similarity
    '''
    if node_i not in node_node_similarity:
        node_node_similarity[node_i]=[]
    node_node_similarity[node_i].append((sim, node_j))



def compute_backbone(pvalue):
    '''
        this function filters the links according to the backbone scheme
        and write the network file using node labels 
        node_id file is also written
    '''
    
    node_ids={}
    f=open('node_id.txt', 'w')
    for n in sorted(node_node_similarity):
        label=len(node_ids)
        node_ids[n]=label
        f.write(str(n)+' '+str(label)+'\n')
    f.close()
    
    f=open(str(pvalue)+'_filtered_graph.txt', 'w')
    for node,sims in node_node_similarity.iteritems():
        #print 'writing for node', node,
        weights=[v[0] for v in sims]
        sum_w=sum(weights)
        weights=[v/sum_w for v in weights]
        #print 'deg', len(weights)
        for i in range(len(weights)):
            if (1-weights[i])**(len(weights)-1)<pvalue:
                f.write(str(node_ids[node])+' '+str(node_ids[sims[i][1]])+' '+str(sims[i][0])+'\n')
    f.close()


if __name__=='__main__':
    
    if len(sys.argv)<3:
        print sys.argv[0], '[similarity_file] [p-value] [inverse]'
        exit()
    
    pvalue=float(sys.argv[2])
    inverse= len(sys.argv)>3 and sys.argv[3]=='inverse'
    print 'inverse is', inverse
    
    # {node_id : [(similarity, node_id)]}
    node_node_similarity={}
    
    for l in open(sys.argv[1]):
        s=l.split(',')
        if inverse==False:
            update_network(s[0], s[1], 1.-float(s[2]), node_node_similarity)
            update_network(s[1], s[0], 1.-float(s[2]), node_node_similarity)
        else:
            weight=1./(float(s[2])+1e-2)
            update_network(s[0], s[1], weight, node_node_similarity)
            update_network(s[1], s[0], weight, node_node_similarity)
            

    #print node_node_similarity, 'node node similarity'    
    compute_backbone(pvalue)
    






